import Sortable from 'sortablejs'
const { t } = useI18n() // 国际化
import { Icon } from '@/components/Icon'
import { useAppStore } from '@/store/modules/app'
const appStore = useAppStore()

import {
  type PropType,
  ref,
  unref,
  computed,
  nextTick,
  defineComponent,
  getCurrentInstance
} from 'vue'

import { delay, cloneDeep, isBoolean, isFunction, getKeyList } from '@pureadmin/utils'

const props = {
  /** 头部最左边的标题 */
  title: {
    type: String,
    default: '列表'
  },
  /** 对于树形表格，如果想启用展开和折叠功能，传入当前表格的ref即可 */
  tableRef: {
    type: Object as PropType<any>
  },
  /** 需要展示的列 */
  columns: {
    type: Array as PropType<any>,
    default: () => []
  },
  isExpandAll: {
    type: Boolean,
    default: true
  },
  tableKey: {
    type: [String, Number] as PropType<string | number>,
    default: '0'
  }
}

export default defineComponent({
  name: 'PureTableBar',
  props,
  emits: ['refresh', 'fullscreen'],
  setup(props, { emit, slots, attrs }) {
    const size = ref('default')
    const loading = ref(false)
    const checkAll = ref(true)
    const isFullscreen = ref(false)
    const isIndeterminate = ref(false)
    const instance = getCurrentInstance()!
    const isExpandAll = ref(props.isExpandAll)
    const filterColumns = cloneDeep(props?.columns).filter((column) =>
      isBoolean(column?.hide) ? !column.hide : !(isFunction(column?.hide) && column?.hide())
    )
    const disabledCheckdColumns = cloneDeep(props?.columns)
      .filter((column) => column.disabledCheck)
      .map((item) => item.label)

    let checkColumnList = getKeyList(cloneDeep(props?.columns), 'label')

    const checkedColumns = ref(getKeyList(cloneDeep(filterColumns), 'label'))
    const dynamicColumns = ref(cloneDeep(props?.columns))
    const getDropdownItemStyle = computed(() => {
      return (s) => {
        return {
          background: s === size.value ? appStore.getTheme.elColorPrimary : '',
          color: s === size.value ? '#fff' : 'var(--el-text-color-primary)'
        }
      }
    })

    const iconClass = computed(() => {
      return [
        'text-black',
        'dark:text-white',
        'duration-100',
        'hover:!text-primary',
        'cursor-pointer',
        'outline-none'
      ]
    })

    const topClass = computed(() => {
      return [
        'flex',
        'justify-between',
        'pt-[3px]',
        'px-[11px]',
        'border-b-[1px]',
        'border-solid',
        'border-[#fff]',
        'dark:border-[#303030]'
      ]
    })

    function onReFresh() {
      loading.value = true
      emit('refresh')
      delay(500).then(() => (loading.value = false))
    }

    function onExpand() {
      isExpandAll.value = !isExpandAll.value
      toggleRowExpansionAll(props.tableRef.data, isExpandAll.value)
    }

    function onFullscreen() {
      isFullscreen.value = !isFullscreen.value
      emit('fullscreen', isFullscreen.value)
    }

    function toggleRowExpansionAll(data, isExpansion) {
      data.forEach((item) => {
        props.tableRef.toggleRowExpansion(item, isExpansion)
        if (item.children !== undefined && item.children !== null) {
          toggleRowExpansionAll(item.children, isExpansion)
        }
      })
    }

    function handleCheckAllChange(val: boolean) {
      checkedColumns.value = val ? checkColumnList : []
      isIndeterminate.value = false
      dynamicColumns.value.map((column) => (val ? (column.hide = false) : (column.hide = true)))
    }

    function handleCheckedColumnsChange(value: string[]) {
      checkedColumns.value = value
      const checkedCount = value.length
      checkAll.value = checkedCount === checkColumnList.length
      isIndeterminate.value = checkedCount > 0 && checkedCount < checkColumnList.length
    }

    function handleCheckColumnListChange(val: boolean, label: string) {
      dynamicColumns.value.filter((item) => t(item.label) === t(label))[0].hide = !val
    }

    async function onReset() {
      checkAll.value = true
      isIndeterminate.value = false
      dynamicColumns.value = cloneDeep(props?.columns)
      checkColumnList = []
      checkColumnList = await getKeyList(cloneDeep(props?.columns), 'label')
      checkedColumns.value = getKeyList(cloneDeep(filterColumns), 'label')
    }

    const dropdown = {
      dropdown: () => (
        <el-dropdown-menu class="translation">
          <el-dropdown-item
            style={getDropdownItemStyle.value('large')}
            onClick={() => (size.value = 'large')}
          >
            宽松
          </el-dropdown-item>
          <el-dropdown-item
            style={getDropdownItemStyle.value('default')}
            onClick={() => (size.value = 'default')}
          >
            默认
          </el-dropdown-item>
          <el-dropdown-item
            style={getDropdownItemStyle.value('small')}
            onClick={() => (size.value = 'small')}
          >
            紧凑
          </el-dropdown-item>
        </el-dropdown-menu>
      )
    }

    /** 列展示拖拽排序 */
    const rowDrop = (event: { preventDefault: () => void }) => {
      event.preventDefault()
      nextTick(() => {
        const wrapper: HTMLElement = (
          instance?.proxy?.$refs[`GroupRef${unref(props.tableKey)}`] as any
        ).$el.firstElementChild
        Sortable.create(wrapper, {
          animation: 300,
          handle: '.drag-btn',
          onEnd: ({ newIndex, oldIndex, item }) => {
            const targetThElem = item
            const wrapperElem = targetThElem.parentNode as HTMLElement
            const oldColumn = dynamicColumns.value[oldIndex]
            const newColumn = dynamicColumns.value[newIndex]
            if (oldColumn?.fixed || newColumn?.fixed) {
              // 当前列存在fixed属性 则不可拖拽
              const oldThElem = wrapperElem.children[oldIndex] as HTMLElement
              if (newIndex > oldIndex) {
                wrapperElem.insertBefore(targetThElem, oldThElem)
              } else {
                wrapperElem.insertBefore(
                  targetThElem,
                  oldThElem ? oldThElem.nextElementSibling : oldThElem
                )
              }
              return
            }
            const currentRow = dynamicColumns.value.splice(oldIndex, 1)[0]
            dynamicColumns.value.splice(newIndex, 0, currentRow)
          }
        })
      })
    }

    const isFixedColumn = (label: string) => {
      return dynamicColumns.value.filter((item) => t(item.label) === t(label))[0].fixed
        ? true
        : false
    }
    const statusFixedColumn = (label: string) => {
      return dynamicColumns.value.filter((item) => t(item.label) === t(label))[0].fixed
    }
    const fixedColumn = (label, fixed) => {
      dynamicColumns.value.filter((item) => t(item.label) === t(label))[0].fixed = fixed
    }

    const reference = {
      reference: () => (
        <div>
          <el-tooltip trigger="hover" content="列设置" placement="top">
            <Icon class={['w-[20px]', iconClass.value]} icon={'ant-design:setting-outlined'} />
          </el-tooltip>
        </div>
      )
    }

    return () => (
      <>
        <div
          {...attrs}
          class={[
            'w-[99/100]',
            'bg-[var(--el-bg-color)]',
            isFullscreen.value ? ['!w-full', '!h-full', 'z-[2002]', 'fixed', 'inset-0'] : ''
          ]}
        >
          <div class="flex justify-between w-full h-[40px]  p-10px">
            {slots?.title ? slots.title() : <p class="font-bold truncate">{props.title}</p>}
            <div class="flex items-center justify-around">
              {slots?.buttons ? <div class="flex mr-4px">{slots.buttons()}</div> : null}
              {props.tableRef?.size ? (
                <>
                  <el-tooltip
                    trigger="hover"
                    content={isExpandAll.value ? '折叠' : '展开'}
                    placement="top"
                  >
                    <Icon
                      icon={'ant-design:expand-alt-outlined'}
                      class={['w-[20px]', iconClass.value]}
                      style={{
                        transform: isExpandAll.value ? 'none' : 'rotate(-90deg)'
                      }}
                      onClick={() => onExpand()}
                    />
                  </el-tooltip>
                  <el-divider direction="vertical" />
                </>
              ) : null}

              <el-tooltip trigger="hover" content="刷新" placement="top">
                <Icon
                  class={['w-[20px]', iconClass.value, loading.value ? 'animate-spin' : '']}
                  onClick={() => onReFresh()}
                  icon="ep:refresh"
                />
              </el-tooltip>

              <el-divider direction="vertical" />
              <el-tooltip trigger="hover" content="密度" placement="top">
                <el-dropdown v-slots={dropdown} trigger="click">
                  <Icon icon={'ic:round-expand'} class={['w-[20px]', iconClass.value]} />
                </el-dropdown>
              </el-tooltip>

              <el-divider direction="vertical" />

              <el-popover
                v-slots={reference}
                placement="bottom-start"
                popper-style={{ padding: 0 }}
                width="200"
                trigger="click"
              >
                <div class={[topClass.value]}>
                  <el-checkbox
                    class="!-mr-1"
                    label="列展示"
                    v-model={checkAll.value}
                    indeterminate={isIndeterminate.value}
                    onChange={(value) => handleCheckAllChange(value)}
                  />
                  <el-button type="primary" link onClick={() => onReset()}>
                    重置
                  </el-button>
                </div>

                <div class="pt-[5px]">
                  <el-scrollbar max-height="36vh">
                    <el-checkbox-group
                      ref={`GroupRef${unref(props.tableKey)}`}
                      modelValue={checkedColumns.value}
                      onChange={(value) => handleCheckedColumnsChange(value)}
                    >
                      <el-space direction="vertical" alignment="flex-start" size={0}>
                        {checkColumnList.map((item, index) => {
                          return (
                            <div class="flex items-center">
                              <Icon
                                class={[
                                  'drag-btn w-[20px] mr-2 ml-2',
                                  isFixedColumn(item) ? '!cursor-no-drop' : '!cursor-grab'
                                ]}
                                onMouseenter={(event: { preventDefault: () => void }) =>
                                  rowDrop(event)
                                }
                                icon="ant-design:drag-outlined"
                              />
                              <el-checkbox
                                key={index}
                                label={item}
                                value={item}
                                disabled={disabledCheckdColumns.includes(item)}
                                onChange={(value) => handleCheckColumnListChange(value, item)}
                              >
                                <span
                                  title={t(item)}
                                  class="inline-block w-[80px] truncate hover:text-text_color_primary"
                                >
                                  {t(item)}
                                </span>
                              </el-checkbox>

                              <Icon
                                class={[
                                  ' w-[20px] mr-2 ml-2',
                                  statusFixedColumn(item) === 'left' ? 'c-[#2080f0]' : 'undefined'
                                ]}
                                color="element.fixed === 'left' ? '#2080f0' : undefined"
                                icon="ant-design:vertical-right-outlined"
                                onClick={() => {
                                  fixedColumn(item, 'left')
                                }}
                              />
                              <Icon
                                class={[
                                  ' w-[20px] mr-2 ml-2',
                                  statusFixedColumn(item) === 'right' ? 'c-[#2080f0]' : 'undefined'
                                ]}
                                color="element.fixed === 'left' ? '#2080f0' : undefined"
                                icon="ant-design:vertical-left-outlined"
                                onClick={() => {
                                  fixedColumn(item, 'right')
                                }}
                              />
                            </div>
                          )
                        })}
                      </el-space>
                    </el-checkbox-group>
                  </el-scrollbar>
                </div>
              </el-popover>
              <el-divider direction="vertical" />
              <el-tooltip
                trigger="hover"
                content={isFullscreen.value ? '退出全屏' : '全屏'}
                placement="top"
              >
                <Icon
                  class={['w-[20px]', iconClass.value]}
                  icon={
                    isFullscreen.value
                      ? 'ant-design:fullscreen-exit-outlined'
                      : 'ant-design:fullscreen-outlined'
                  }
                  onClick={() => onFullscreen()}
                />
              </el-tooltip>
            </div>
          </div>
          {slots.default({
            size: size.value,
            dynamicColumns: dynamicColumns.value
          })}
        </div>
      </>
    )
  }
})
